package com.weactivity.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.weactivity.dto.Result;
import com.weactivity.dto.UserDTO;
import com.weactivity.dto.registerFormDTO;
import com.weactivity.entity.User;
import com.weactivity.mapper.UserMapper;
import com.weactivity.service.UserService;
import com.weactivity.utils.Md5Util;
import com.weactivity.utils.RedisConstant;
import com.weactivity.utils.RegexUtils;
import com.weactivity.utils.UserHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpSession;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private UserMapper userMapper;


    /**
     * 发送验证码
     * 1.用户手机号是否满足格式，前端需要进行格式校验，后端也需要
     * 2.符合，生成验证码
     * 3.将验证码存放在redis中
     *
     * @param phone
     * @param session
     * @return
     */
    @Override
    public Result sendCode(String phone, HttpSession session) {
        //验证手机号格式
        if (RegexUtils.isPhoneInvalid(phone)) {
            return Result.fail("手机号格式错误");
        }
        //生成验证码
        String code = RandomUtil.randomNumbers(6);

        //以login:code:phone(phone是标识)作为键，code作为值,有效期2分钟
        stringRedisTemplate.opsForValue().set(RedisConstant.LOGIN_CODE_KEY + phone, code, RedisConstant.LOGIN_CODE_TTL, TimeUnit.MINUTES);

        //发送验证码
        //模拟 调用第三方API发送信息给手机
        log.debug("验证码：" + code);
        return Result.ok();
    }
    //重载,匹配业务

    /**
     * @param phone          手机号
     * @param session
     * @param businessPrefix 业务前缀，用来区分不同业务的验证码
     * @param persistTime    验证码持续时间
     * @param timeUnit       时间单位
     * @return
     */
    @Override
    public Result sendCode(String phone, HttpSession session, String businessPrefix, Long persistTime, TimeUnit timeUnit) {
        //验证手机号格式
        if (RegexUtils.isPhoneInvalid(phone)) {
            return Result.fail("手机号格式错误");
        }
        //生成验证码
        String code = RandomUtil.randomNumbers(6);
        //存入redis里面的key
        String key = businessPrefix + phone;

        if(null != stringRedisTemplate.opsForValue().get(key)){
            //如果非空，说明已经发过验证码了
            return Result.fail("验证码已发送，请等1分钟后重试");
        }
        //以businessPrefix:phone(phone是标识)作为键，code作为值,有效期2分钟
        stringRedisTemplate.opsForValue().set(key, code, persistTime, timeUnit);

        //发送验证码
        //模拟 调用第三方API发送信息给手机
        log.debug(businessPrefix + "验证码：" + code);
        return Result.ok();
    }

    /**
     * 用户注册的接口
     * 步骤：
     * 用户输入手机号和验证码进行注册
     * 并且设置密码
     *
     * @param registerForm
     * @param session
     * @return
     */

    @Override
    public Result register(registerFormDTO registerForm, HttpSession session) {
        //注册的流程
        //用户输入phone,code,password
        //code如何生成
        String phone = registerForm.getPhone();


        String key = RedisConstant.REGISTER_CODE_KEY + phone;
        String code = registerForm.getCode();

        String redisCode = stringRedisTemplate.opsForValue().get(key);
        if (!code.equals(redisCode)) {
            //说明验证失败
//            System.out.println("rediscode"+redisCode);
//            System.out.println("code"+code);
            return Result.fail("验证码不一致");
        }
        //到这步表示已经可以注册用户了
        //数据存储到newUser中
        User newUser = new User();
        /*String md5Password = Md5Util.getMD5String(registerForm.getPassword());
        if(null == md5Password){
            return Result.fail("密码加密失败");
        }*/
        //2024.5.16 出现问题 密码无法传过来 这里getPassword()返回空
        //已解决:原因是RegisterForm类中在密码属性上添加了@JsonIgnore注解
        String password = Md5Util.getMD5String(registerForm.getPassword());
        newUser.setPhone(phone);
        newUser.setPassword(password );
        newUser.setCreateTime(LocalDateTime.now());
        //返回操作记录数
        int insertCount = userMapper.insertUser(newUser);
        if (insertCount != 1) {
            return Result.fail("注册失败");
        }
        //返给前端注册成功的消息 String类型
        return Result.ok("注册成功");
    }

    @Override
    public User findByPhone(String phone) {
        return query().eq("phone", phone).one();
    }

    @Override
    public User findByUserName(String userName) {
        User u = userMapper.findByUserName(userName);
        return u;
    }

    @Override
    public User findByUserNameOrId(String keyword){

        User u = userMapper.findByKeyword(keyword);
        return u;

    }

    @Override
    public String findNameById(int uid) {
        return userMapper.findNameById(uid);
    }

    @Override
    public int updatePassword(String phone,String md5String) {
        UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();
        userUpdateWrapper.eq("phone",phone).set("password",md5String);
        int update = userMapper.update(null, userUpdateWrapper);
        return update;
    }

    /**
     * 返回用户信息
     * @return
     */
    @Override
    public Map<String, Object> findUserInfo() {
        UserDTO user = UserHolder.getUser();
        return null;
    }
}
